home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / base / netkit-b.07a / netkit-b / NetKit-B-0.07A / talkd / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  6.1 KB  |  223 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. /*
  35.  * From: @(#)process.c    5.10 (Berkeley) 2/26/91
  36.  */
  37. char rcsid[] = 
  38.   "$Id: process.c,v 1.2 1996/07/16 05:01:32 dholland Exp $";
  39.  
  40. /*
  41.  * process.c handles the requests, which can be of three types:
  42.  *    ANNOUNCE - announce to a user that a talk is wanted
  43.  *    LEAVE_INVITE - insert the request into the table
  44.  *    LOOK_UP - look up to see if a request is waiting in
  45.  *          in the table for the local user
  46.  *    DELETE - delete invitation
  47.  */
  48. #include <sys/param.h>
  49. #include <sys/stat.h>
  50. #include <sys/socket.h>
  51. #include <netinet/in.h>
  52. #include <protocols/talkd.h>
  53. #include <netdb.h>
  54. #include <syslog.h>
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <paths.h>
  58. #include <utmp.h>
  59. #include "proto.h"
  60.  
  61. static void do_announce(CTL_MSG *mp, CTL_RESPONSE *rp);
  62. static int find_user(char *name, char *tty);
  63.  
  64. void
  65. process_request(CTL_MSG *mp, CTL_RESPONSE *rp)
  66. {
  67.     CTL_MSG *ptr;
  68.     extern int debug;
  69.  
  70.     rp->vers = TALK_VERSION;
  71.     rp->type = mp->type;
  72.     rp->id_num = htonl(0);
  73.     if (mp->vers != TALK_VERSION) {
  74.         syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
  75.         rp->answer = BADVERSION;
  76.         return;
  77.     }
  78.     mp->id_num = ntohl(mp->id_num);
  79.     mp->addr.sa_family = ntohs(mp->addr.sa_family);
  80.     if (mp->addr.sa_family != AF_INET) {
  81.         syslog(LOG_WARNING, "Bad address, family %d",
  82.             mp->addr.sa_family);
  83.         rp->answer = BADADDR;
  84.         return;
  85.     }
  86.     mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
  87.     if (mp->ctl_addr.sa_family != AF_INET) {
  88.         syslog(LOG_WARNING, "Bad control address, family %d",
  89.             mp->ctl_addr.sa_family);
  90.         rp->answer = BADCTLADDR;
  91.         return;
  92.     }
  93.     mp->pid = ntohl(mp->pid);
  94.     if (debug) print_request("process_request", mp);
  95.  
  96.     switch (mp->type) {
  97.       case ANNOUNCE:
  98.         do_announce(mp, rp);
  99.         break;
  100.       case LEAVE_INVITE:
  101.         ptr = find_request(mp);
  102.         if (ptr != (CTL_MSG *)0) {
  103.             rp->id_num = htonl(ptr->id_num);
  104.             rp->answer = SUCCESS;
  105.         } 
  106.         else insert_table(mp, rp);
  107.         break;
  108.       case LOOK_UP:
  109.         ptr = find_match(mp);
  110.         if (ptr != (CTL_MSG *)0) {
  111.             rp->id_num = htonl(ptr->id_num);
  112.             rp->addr = ptr->addr;
  113.             rp->addr.sa_family = htons(ptr->addr.sa_family);
  114.             rp->answer = SUCCESS;
  115.         } 
  116.         else rp->answer = NOT_HERE;
  117.         break;
  118.       case DELETE:
  119.         rp->answer = delete_invite(mp->id_num);
  120.         break;
  121.       default:
  122.         rp->answer = UNKNOWN_REQUEST;
  123.         break;
  124.     }
  125.     if (debug) print_response("process_request", rp);
  126. }
  127.  
  128. static void
  129. do_announce(CTL_MSG *mp, CTL_RESPONSE *rp)
  130. {
  131.     struct hostent *hp;
  132.     CTL_MSG *ptr;
  133.     int result;
  134.     struct in_addr the_addr;
  135.  
  136.     /* see if the user is logged */
  137.     result = find_user(mp->r_name, mp->r_tty);
  138.     if (result != SUCCESS) {
  139.         rp->answer = result;
  140.         return;
  141.     }
  142.     the_addr = ((struct sockaddr_in *)(&mp->ctl_addr))->sin_addr;
  143.     hp = gethostbyaddr((char *)&the_addr, sizeof(the_addr), AF_INET);
  144.     if (hp == NULL) {
  145.         rp->answer = MACHINE_UNKNOWN;
  146.         return;
  147.     }
  148.     ptr = find_request(mp);
  149.     if (ptr == NULL) {
  150.         insert_table(mp, rp);
  151.         rp->answer = announce(mp, hp->h_name);
  152.         return;
  153.     }
  154.     if (mp->id_num > ptr->id_num) {
  155.         /*
  156.          * This is an explicit re-announce, so update the id_num
  157.          * field to avoid duplicates and re-announce the talk.
  158.          */
  159.         ptr->id_num = new_id();
  160.         rp->id_num = htonl(ptr->id_num);
  161.         rp->answer = announce(mp, hp->h_name);
  162.     } 
  163.     else {
  164.         /* a duplicated request, so ignore it */
  165.         rp->id_num = htonl(ptr->id_num);
  166.         rp->answer = SUCCESS;
  167.     }
  168. }
  169.  
  170. /*
  171.  * Search utmp for the local user
  172.  */
  173. static int
  174. find_user(char *name, char *tty)
  175. {
  176.     struct utmp ubuf;
  177.     int status;
  178.     FILE *fd;
  179.     struct stat statb;
  180.     char ftty[20];
  181.     time_t last_time = 0;
  182.     int notty;
  183.  
  184.     notty = (*tty == '\0');
  185.  
  186.     if ((fd = fopen(_PATH_UTMP, "r")) == NULL) {
  187.         fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP);
  188.         return (FAILED);
  189.     }
  190.     status = NOT_HERE;
  191.     strcpy(ftty, _PATH_DEV);
  192.     status = PERMISSION_DENIED;
  193.     while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) {
  194. #ifdef USER_PROCESS
  195.         if (ubuf.ut_type!=USER_PROCESS) continue;
  196. #endif
  197.         if (!strncmp(ubuf.ut_name, name, sizeof(ubuf.ut_name))) {
  198.             if (notty) {
  199.                 /* no particular tty was requested */
  200.                 strncpy(ftty+5, ubuf.ut_line, sizeof(ftty)-5);
  201.                 ftty[sizeof(ftty)-1] = 0;
  202.  
  203.                 if (stat(ftty,&statb) == 0) {
  204.                     if (!(statb.st_mode & 020))
  205.                         continue;
  206.                     if (statb.st_atime > last_time) {
  207.                         last_time = statb.st_atime;
  208.                         strcpy(tty, ubuf.ut_line);
  209.                         status = SUCCESS;
  210.                     }
  211.                     continue;
  212.                 }
  213.             }
  214.             if (!strcmp(ubuf.ut_line, tty)) {
  215.                 status = SUCCESS;
  216.                 break;
  217.             }
  218.         }
  219.     }
  220.     fclose(fd);
  221.     return status;
  222. }
  223.